package com.zxmzy.scaffold.core.utils

import android.content.res.Resources
import android.util.DisplayMetrics
import android.util.Log
import com.zxmzy.scaffold.core.ext.saveAsUnChecked
import java.lang.reflect.Field

/**
 * @author zhangxiaoming
 * @date 2023/8/10
 * @description
 */
object AdaptScreenUtils {
    private var isInitMiui: Boolean = false
    private var mTmpMetricsField: Field? = null

    fun adaptWidth(resources: Resources, designWidth: Int): Resources {
        val dm: DisplayMetrics = getDisplayMetrics(resources)
        val newXdpi: Float = ((dm.widthPixels * 72f) / designWidth).also { dm.xdpi = it }
        setAppDmXdpi(newXdpi)
        return resources
    }

    fun adaptHeight(resources: Resources, designHeight: Int): Resources {
        val dm: DisplayMetrics = getDisplayMetrics(resources)

        val newXdpi = (dm.heightPixels * 72f / designHeight).also { dm.xdpi = it }
        setAppDmXdpi(newXdpi)
        return resources
    }

    fun closeAdapt(resources: Resources): Resources {
        val dm: DisplayMetrics = getDisplayMetrics(resources)
        val newXdpi = (dm.density * 72).also { dm.xdpi = it }
        setAppDmXdpi(newXdpi)
        return resources
    }

    private fun setAppDmXdpi(xdpi: Float) {
        appContext.resources.displayMetrics.xdpi = xdpi
    }

    private fun getDisplayMetrics(resources: Resources): DisplayMetrics {
        val miuiDisplayMetrics: DisplayMetrics? = getMiuiTmpMetrics(resources)
        return miuiDisplayMetrics ?: resources.displayMetrics
    }

    private fun getMiuiTmpMetrics(resources: Resources): DisplayMetrics? {
        if (!isInitMiui) {
            var ret: DisplayMetrics? = null
            val simpleName = resources.javaClass.simpleName
            if ("MiuiResources".equals(simpleName) || "XResources".equals(simpleName)) {
                try {
                    mTmpMetricsField = Resources::class.java.getDeclaredField("mTmpMetrics")
                    mTmpMetricsField?.isAccessible = true
                    ret = mTmpMetricsField?.get(resources)?.saveAsUnChecked()
                } catch (e: Exception) {
                    Log.e("AdaptScreenUtils", "no field of mTmpMetrics in resources.")
                }
            }
            isInitMiui = true
            return ret
        }
        if (mTmpMetricsField == null) {
            return null
        }
        return try {
            mTmpMetricsField?.get(resources)?.saveAsUnChecked()
        } catch (e: Exception) {
            null
        }
    }
}